package top.xzxsrq.JavaFileAnalysisTool.utils;

import com.github.javaparser.JavaParser;
import com.github.javaparser.ParseResult;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.expr.AnnotationExpr;
import com.github.javaparser.ast.visitor.GenericVisitorAdapter;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.Optional;

/**
 * @program: MyUtils
 * @create: 2021-08-28 13:12
 **/
public abstract class JavaFileAnalys {

    public static Boolean isByAnnotationName(CompilationUnit cu, String annotationName) {
        Boolean find = cu.accept(new GenericVisitorAdapter<Boolean, Void>() {
            @Override
            public Boolean visit(ClassOrInterfaceDeclaration n, Void arg) {
                Optional<AnnotationExpr> tableName = n.getAnnotationByName(annotationName);
                return tableName.isPresent();
            }
        }, null);
        if (find == null) {
            return false;
        } else {
            return find;
        }
    }

    public static Boolean isByAnnotationNameContains(CompilationUnit cu, String annotationName) {
        Boolean find = cu.accept(new GenericVisitorAdapter<Boolean, Void>() {
            @Override
            public Boolean visit(ClassOrInterfaceDeclaration n, Void arg) {
                for (AnnotationExpr annotation : n.getAnnotations()) {
                    String nameAsString = annotation.getNameAsString();
                    if (nameAsString.contains(annotationName)) {
                        return true;
                    }
                }
                return false;
            }
        }, null);
        if (find == null) {
            return false;
        } else {
            return find;
        }
    }

    public static Boolean isByAnnotationNameContains(CompilationUnit cu, String[] annotationNames) {
        Boolean find = cu.accept(new GenericVisitorAdapter<Boolean, Void>() {
            @Override
            public Boolean visit(ClassOrInterfaceDeclaration n, Void arg) {
                for (AnnotationExpr annotation : n.getAnnotations()) {
                    String nameAsString = annotation.getNameAsString();
                    if (Arrays.stream(annotationNames).anyMatch(nameAsString::contains)) {
                        return true;
                    }
                }
                return false;
            }
        }, null);
        if (find == null) {
            return false;
        } else {
            return find;
        }
    }

    public static Boolean isByAnnotationNameOr(CompilationUnit cu, String[] annotationNames) {
        Boolean find = cu.accept(new GenericVisitorAdapter<Boolean, Void>() {
            @Override
            public Boolean visit(ClassOrInterfaceDeclaration n, Void arg) {
                for (String annotationName : annotationNames) {
                    Optional<AnnotationExpr> tableName = n.getAnnotationByName(annotationName);
                    if (tableName.isPresent()) {
                        return true;
                    }
                }
                return false;
            }
        }, null);
        if (find == null) {
            return false;
        } else {
            return find;
        }
    }

    public static CompilationUnit get(String path) {
        return get(new File(path));
    }

    public static CompilationUnit get(File file) {
        JavaParser parser = new JavaParser(); // 解析工具
        ParseResult<CompilationUnit> parse = null;
        try {
            parse = parser.parse(file);
            Optional<CompilationUnit> result = parse.getResult();
            return result.orElse(null);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * com.sinra.link.value.excel.converter.KeepTwoFloatConverter
     *
     * @param n
     * @param classFullPath
     */
    public static void addImport(CompilationUnit n, String classFullPath) {
        n.addImport(classFullPath);
    }

}
